#include "network_heartbeat.h"

#include <assert.h>
#include <core/system/tick_util.h>
#include <core/observer/message_observer.h>

#define BACGROUND_RECONNECT_TIMESPAN 20

namespace qb {
CNetworkHeartBeat::CNetworkHeartBeat()
    : m_pTimerImpl(NULL), m_nIDTNetworkCheck(-1) {}

CNetworkHeartBeat::~CNetworkHeartBeat() {
  assert(0 == m_notifys.size());
  assert(NULL == m_pTimerImpl);
  assert(-1 == m_nIDTNetworkCheck);

  Destroy();
}

void CNetworkHeartBeat::Create() {
  QB_CHECK_RETURN_VOID_ASSERT1(NULL == m_pTimerImpl);
  m_pTimerImpl = qb::TimerWrapper::CreateTimer();

  StartNetworkTimer();
}

void CNetworkHeartBeat::Destroy() {
  StopNetworkTimer();
  RemoveObserver<INetworkHeartBeatNotify>(m_notifys);

  QB_CHECK_RETURN_VOID1(m_pTimerImpl);
  delete m_pTimerImpl;
  m_pTimerImpl = NULL;
}

void CNetworkHeartBeat::OnTimer(int32_t nIDTTImer) {
  if (nIDTTImer == m_nIDTNetworkCheck) {
    OnNetworkCheckProc();
  }
}

void CNetworkHeartBeat::RegisterNotify(INetworkHeartBeatNotify* pNotify) {
  RegisterObserver<INetworkHeartBeatNotify>(pNotify, m_notifys);
}

void CNetworkHeartBeat::DeRegisterNotify(INetworkHeartBeatNotify* pNotify) {
  DeRegisterObserver<INetworkHeartBeatNotify>(pNotify, m_notifys);
}

void OnNetworkHeartBeatProc(int32_t timerID, void* userData) {
  CNetworkHeartBeat* pNetworkHeartBeat = (CNetworkHeartBeat*)userData;
  QB_CHECK_RETURN_VOID_ASSERT1(pNetworkHeartBeat);

  pNetworkHeartBeat->OnTimer(timerID);
}

void CNetworkHeartBeat::StartNetworkTimer() {
  QB_CHECK_RETURN_VOID1(m_pTimerImpl);
  QB_CHECK_RETURN_VOID1(-1 == m_nIDTNetworkCheck);

  m_nIDTNetworkCheck =
      m_pTimerImpl->SetTimer(45 * 1000, OnNetworkHeartBeatProc, this);
}

void CNetworkHeartBeat::StopNetworkTimer() {
  QB_CHECK_RETURN_VOID1(m_pTimerImpl);
  QB_CHECK_RETURN_VOID1(m_nIDTNetworkCheck != -1);

  m_pTimerImpl->KillTimer(m_nIDTNetworkCheck);
  m_nIDTNetworkCheck = -1;
}

void CNetworkHeartBeat::OnNetworkCheckProc() {
  BList<INetworkHeartBeatNotify*>::iterator iter = m_notifys.begin();
  for_each_list(m_notifys, iter, (iter++)->first->OnHeartBeat());
}
}  // namespace qb
